#pragma once

#include "IEntityController.h"
#include "IBehavior.h"

#include "OrientationComponent.h"
#include "RigidBodyComponent.h"
#include "StatusComponent.h"
#include "CombatComponent.h"

#include "Vehicle.h"
#include "Obstacle.h"
#include "World.h"

#include "Vector3D.h"
#include "Trigger.h"
#include "IAbility.h"

class AIEntityController : public IEntityController
{
public:	
	static const HashedString type;

	AIEntityController( Entity* entity );
	virtual ~AIEntityController() {};
	const HashedString& Type();

	// Utility functions
	void UpdateVelocity( Maths::Vector3D& velocity );
	void UpdateDestination( Maths::Vector3D& destination );
	void UpdateStatus( HashedString status, int value );
	void UpdateDirectionNode();
	void UpdatePath();
	void getPosition( Maths::Vector3D& position );
	void getStatus( HashedString status, int& value );
	void getDirection( Maths::Vector3D& direction );
	void setWorld( Pointer<Pathing::World>& world );
	void LinkPosition( Subject<Maths::Vector3D>& position );
	void PushWaypoint( Maths::Vector3D& waypoint );
	Pathing::Vehicle& Vehicle();
	Maths::Vector3D PopWaypoint();
	std::list<Maths::Vector3D>& getWaypoints();

	Combat::IAbility::Vector_t& getAbilities();
	
	void Behavior( Pointer<IBehavior> behavior );
	Pointer<IBehavior> Behavior( );

	void Update();

	void ToXML( tinyxml2::XMLPrinter& printer );
private:
	Pointer<TriggerBase> m_position;

	// Components ai has control over
	OrientationComponent* m_orientation;
	RigidBodyComponent* m_rigidbody;
	StatusComponent* m_status;
	CombatComponent* m_combat;
	
	// Behavior
	Pointer<IBehavior> m_behavior;

	// Pathings objects
	std::list<Maths::Vector3D> m_waypoints;
	Pathing::Vehicle m_vehicle;
	Pointer<Pathing::World> m_world;
};